// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception


// Copyright 2018 Ulf Adams
// Copyright (c) Microsoft Corporation. All rights reserved.

// Boost Software License - Version 1.0 - August 17th, 2003

// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:

// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.


// This file contains test cases derived from:
// https://github.com/ulfjack/ryu
// See xcharconv_ryu.h for the exact commit.
// (Keep the cgmanifest.json commitHash in sync.)


#pragma once

#include <charconv>

#include "test.hpp"
using namespace std;

inline constexpr DoublePrecisionToCharsTestCase double_fixed_precision_to_chars_test_cases_1[] = {
    // Test special cases (zero, inf, nan) and an ordinary case. Also test negative signs.
    {0.0, chars_format::fixed, 4, "0.0000"},
    {-0.0, chars_format::fixed, 4, "-0.0000"},
    {double_inf, chars_format::fixed, 4, "inf"},
    {-double_inf, chars_format::fixed, 4, "-inf"},
    {double_nan, chars_format::fixed, 4, "nan"},
    {-double_nan, chars_format::fixed, 4, "-nan(ind)"},
    {double_nan_payload, chars_format::fixed, 4, "nan"},
    {-double_nan_payload, chars_format::fixed, 4, "-nan"},
    {1.729, chars_format::fixed, 4, "1.7290"},
    {-1.729, chars_format::fixed, 4, "-1.7290"},

    // Ryu Printf d2fixed_test.cc D2fixedTest Basic
    {0x1.000000001869fp+211, chars_format::fixed, 0,
        "3291009114715486435425664845573426149758869524108446525879746560"},

    // Ryu Printf d2fixed_test.cc D2fixedTest Zero
    {0.0, chars_format::fixed, 4, "0.0000"},
    {0.0, chars_format::fixed, 3, "0.000"},
    {0.0, chars_format::fixed, 2, "0.00"},
    {0.0, chars_format::fixed, 1, "0.0"},
    {0.0, chars_format::fixed, 0, "0"},

    // Ryu Printf d2fixed_test.cc D2fixedTest MinMax
    {0x0.0000000000001p-1022, chars_format::fixed, 1074,
        "0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000000000049406564584124654417656879286822137"
        "236505980261432476442558568250067550727020875186529983636163599237979656469544571773092665"
        "671035593979639877479601078187812630071319031140452784581716784898210368871863605699873072"
        "305000638740915356498438731247339727316961514003171538539807412623856559117102665855668676"
        "818703956031062493194527159149245532930545654440112748012970999954193198940908041656332452"
        "475714786901472678015935523861155013480352649347201937902681071074917033322268447533357208"
        "324319360923828934583680601060115061698097530783422773183292479049825247307763759272478746"
        "560847782037344696995336470179726777175851256605511991315048911014510378627381672509558373"
        "89733598993664809941164205702637090279242767544565229087538682506419718265533447265625"},

    {0x1.fffffffffffffp+1023, chars_format::fixed, 0,
        "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558"
        "632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245"
        "490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168"
        "738177180919299881250404026184124858368"},

    // Test more corner cases.
    {0x0.fffffffffffffp-1022, chars_format::fixed, 1074,
        "0."
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585"
        "0720088902458687608585988765042311224095946549352480256244000922823569517877588880375915526423097809504343"
        "1208587738715835729182199302029437922422355981982750124204178896957131179108226104397197960400045489739193"
        "8079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429"
        "1050802018159266421349966065178030950759130587198464239060686371020051087232827846788436319445158661350412"
        "2347901479236958520832159762106637540161373658304419360371477835530668283453563400507407304013560296804637"
        "5918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417"
        "9060225895030235019375197730309457631732108525072993050897615825191597207572324554347709124613174935802817"
        "34466552734375"}, // max subnormal
    {0x1p-1022, chars_format::fixed, 1022,
        "0."
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585"
        "0720138309023271733240406421921598046233183055332741688720443481391819585428315901251102056406733973103581"
        "1005152434161553460108856012385377718821130777993532002330479610147442583636071921565046942503734208375250"
        "8066506166581589487204911799685916396485006359087701183048747997808877537499494515804516050509153998565824"
        "7081864511353793580499211598108576605199243335211435239014879569960959128889160299264151106346631339366347"
        "7586513029371762047325631781485664350872122828637642044846811407613911477062801689853244110024161447421618"
        "5671661505401542850847167529019031613227788967297073731233340869889831750678388469260927739779728586596549"
        "41091369095406136467568702398678315290680984617210924625396728515625"}, // min normal

    // Ryu Printf d2fixed_test.cc D2fixedTest RoundToEven
    {0.125, chars_format::fixed, 3, "0.125"},
    {0.125, chars_format::fixed, 2, "0.12"},
    {0.375, chars_format::fixed, 3, "0.375"},
    {0.375, chars_format::fixed, 2, "0.38"},

    // Ryu Printf d2fixed_test.cc D2fixedTest RoundToEvenInteger
    {2.5, chars_format::fixed, 1, "2.5"},
    {2.5, chars_format::fixed, 0, "2"},
    {3.5, chars_format::fixed, 1, "3.5"},
    {3.5, chars_format::fixed, 0, "4"},

    // Ryu Printf d2fixed_test.cc D2fixedTest NonRoundToEvenScenarios
    {0.748046875, chars_format::fixed, 3, "0.748"},
    {0.748046875, chars_format::fixed, 2, "0.75"},
    {0.748046875, chars_format::fixed, 1, "0.7"}, // 0.75 would round to "0.8", but this is smaller

    {0.2509765625, chars_format::fixed, 3, "0.251"},
    {0.2509765625, chars_format::fixed, 2, "0.25"},
    {0.2509765625, chars_format::fixed, 1, "0.3"}, // 0.25 would round to "0.2", but this is larger

    {0x1.0000000000001p-2, chars_format::fixed, 54, "0.250000000000000055511151231257827021181583404541015625"},
    {0x1.0000000000001p-2, chars_format::fixed, 3, "0.250"},
    {0x1.0000000000001p-2, chars_format::fixed, 2, "0.25"},
    {0x1.0000000000001p-2, chars_format::fixed, 1, "0.3"}, // 0.25 would round to "0.2", but this is larger (again)

    // More rounding tests.
    {9.5, chars_format::fixed, 1, "9.5"},
    {9.5, chars_format::fixed, 0, "10"},
    {10.5, chars_format::fixed, 1, "10.5"},
    {10.5, chars_format::fixed, 0, "10"},

    {1.241, chars_format::fixed, 3, "1.241"},
    {1.241, chars_format::fixed, 1, "1.2"},
    {1.251, chars_format::fixed, 3, "1.251"},
    {1.251, chars_format::fixed, 1, "1.3"},
    {1.261, chars_format::fixed, 3, "1.261"},
    {1.261, chars_format::fixed, 1, "1.3"},
    {1.341, chars_format::fixed, 3, "1.341"},
    {1.341, chars_format::fixed, 1, "1.3"},
    {1.351, chars_format::fixed, 3, "1.351"},
    {1.351, chars_format::fixed, 1, "1.4"},
    {1.361, chars_format::fixed, 3, "1.361"},
    {1.361, chars_format::fixed, 1, "1.4"},

    {2.41, chars_format::fixed, 2, "2.41"},
    {2.41, chars_format::fixed, 0, "2"},
    {2.51, chars_format::fixed, 2, "2.51"},
    {2.51, chars_format::fixed, 0, "3"},
    {2.61, chars_format::fixed, 2, "2.61"},
    {2.61, chars_format::fixed, 0, "3"},
    {3.41, chars_format::fixed, 2, "3.41"},
    {3.41, chars_format::fixed, 0, "3"},
    {3.51, chars_format::fixed, 2, "3.51"},
    {3.51, chars_format::fixed, 0, "4"},
    {3.61, chars_format::fixed, 2, "3.61"},
    {3.61, chars_format::fixed, 0, "4"},

    // Ryu Printf d2fixed_test.cc D2fixedTest VaryingPrecision
    {1729.142857142857, chars_format::fixed, 47, "1729.14285714285711037518922239542007446289062500000"},
    {1729.142857142857, chars_format::fixed, 46, "1729.1428571428571103751892223954200744628906250000"},
    {1729.142857142857, chars_format::fixed, 45, "1729.142857142857110375189222395420074462890625000"},
    {1729.142857142857, chars_format::fixed, 44, "1729.14285714285711037518922239542007446289062500"},
    {1729.142857142857, chars_format::fixed, 43, "1729.1428571428571103751892223954200744628906250"},
    {1729.142857142857, chars_format::fixed, 42, "1729.142857142857110375189222395420074462890625"},
    {1729.142857142857, chars_format::fixed, 41, "1729.14285714285711037518922239542007446289062"},
    {1729.142857142857, chars_format::fixed, 40, "1729.1428571428571103751892223954200744628906"},
    {1729.142857142857, chars_format::fixed, 39, "1729.142857142857110375189222395420074462891"},
    {1729.142857142857, chars_format::fixed, 38, "1729.14285714285711037518922239542007446289"},
    {1729.142857142857, chars_format::fixed, 37, "1729.1428571428571103751892223954200744629"},
    {1729.142857142857, chars_format::fixed, 36, "1729.142857142857110375189222395420074463"},
    {1729.142857142857, chars_format::fixed, 35, "1729.14285714285711037518922239542007446"},
    {1729.142857142857, chars_format::fixed, 34, "1729.1428571428571103751892223954200745"},
    {1729.142857142857, chars_format::fixed, 33, "1729.142857142857110375189222395420074"},
    {1729.142857142857, chars_format::fixed, 32, "1729.14285714285711037518922239542007"},
    {1729.142857142857, chars_format::fixed, 31, "1729.1428571428571103751892223954201"},
    {1729.142857142857, chars_format::fixed, 30, "1729.142857142857110375189222395420"},
    {1729.142857142857, chars_format::fixed, 29, "1729.14285714285711037518922239542"},
    {1729.142857142857, chars_format::fixed, 28, "1729.1428571428571103751892223954"},
    {1729.142857142857, chars_format::fixed, 27, "1729.142857142857110375189222395"},
    {1729.142857142857, chars_format::fixed, 26, "1729.14285714285711037518922240"},
    {1729.142857142857, chars_format::fixed, 25, "1729.1428571428571103751892224"},
    {1729.142857142857, chars_format::fixed, 24, "1729.142857142857110375189222"},
    {1729.142857142857, chars_format::fixed, 23, "1729.14285714285711037518922"},
    {1729.142857142857, chars_format::fixed, 22, "1729.1428571428571103751892"},
    {1729.142857142857, chars_format::fixed, 21, "1729.142857142857110375189"},
    {1729.142857142857, chars_format::fixed, 20, "1729.14285714285711037519"},
    {1729.142857142857, chars_format::fixed, 19, "1729.1428571428571103752"},
    {1729.142857142857, chars_format::fixed, 18, "1729.142857142857110375"},
    {1729.142857142857, chars_format::fixed, 17, "1729.14285714285711038"},
    {1729.142857142857, chars_format::fixed, 16, "1729.1428571428571104"},
    {1729.142857142857, chars_format::fixed, 15, "1729.142857142857110"},
    {1729.142857142857, chars_format::fixed, 14, "1729.14285714285711"},
    {1729.142857142857, chars_format::fixed, 13, "1729.1428571428571"},
    {1729.142857142857, chars_format::fixed, 12, "1729.142857142857"},
    {1729.142857142857, chars_format::fixed, 11, "1729.14285714286"},
    {1729.142857142857, chars_format::fixed, 10, "1729.1428571429"},
    {1729.142857142857, chars_format::fixed, 9, "1729.142857143"},
    {1729.142857142857, chars_format::fixed, 8, "1729.14285714"},
    {1729.142857142857, chars_format::fixed, 7, "1729.1428571"},
    {1729.142857142857, chars_format::fixed, 6, "1729.142857"},
    {1729.142857142857, chars_format::fixed, 5, "1729.14286"},
    {1729.142857142857, chars_format::fixed, 4, "1729.1429"},
    {1729.142857142857, chars_format::fixed, 3, "1729.143"},
    {1729.142857142857, chars_format::fixed, 2, "1729.14"},
    {1729.142857142857, chars_format::fixed, 1, "1729.1"},
    {1729.142857142857, chars_format::fixed, 0, "1729"},

    // Negative precision requests 6 digits of precision.
    {1729.142857142857, chars_format::fixed, -1, "1729.142857"},
    {1729.142857142857, chars_format::fixed, -2, "1729.142857"},
    {1729.142857142857, chars_format::fixed, -3, "1729.142857"},

    // Ryu Printf d2fixed_test.cc D2fixedTest Carrying
    {0.0009, chars_format::fixed, 4, "0.0009"},
    {0.0009, chars_format::fixed, 3, "0.001"},
    {0.0029, chars_format::fixed, 4, "0.0029"},
    {0.0029, chars_format::fixed, 3, "0.003"},
    {0.0099, chars_format::fixed, 4, "0.0099"},
    {0.0099, chars_format::fixed, 3, "0.010"},
    {0.0299, chars_format::fixed, 4, "0.0299"},
    {0.0299, chars_format::fixed, 3, "0.030"},
    {0.0999, chars_format::fixed, 4, "0.0999"},
    {0.0999, chars_format::fixed, 3, "0.100"},
    {0.2999, chars_format::fixed, 4, "0.2999"},
    {0.2999, chars_format::fixed, 3, "0.300"},
    {0.9999, chars_format::fixed, 4, "0.9999"},
    {0.9999, chars_format::fixed, 3, "1.000"},
    {2.9999, chars_format::fixed, 4, "2.9999"},
    {2.9999, chars_format::fixed, 3, "3.000"},
    {9.9999, chars_format::fixed, 4, "9.9999"},
    {9.9999, chars_format::fixed, 3, "10.000"},
    {29.9999, chars_format::fixed, 4, "29.9999"},
    {29.9999, chars_format::fixed, 3, "30.000"},
    {99.9999, chars_format::fixed, 4, "99.9999"},
    {99.9999, chars_format::fixed, 3, "100.000"},
    {299.9999, chars_format::fixed, 4, "299.9999"},
    {299.9999, chars_format::fixed, 3, "300.000"},

    {0.09, chars_format::fixed, 2, "0.09"},
    {0.09, chars_format::fixed, 1, "0.1"},
    {0.29, chars_format::fixed, 2, "0.29"},
    {0.29, chars_format::fixed, 1, "0.3"},
    {0.99, chars_format::fixed, 2, "0.99"},
    {0.99, chars_format::fixed, 1, "1.0"},
    {2.99, chars_format::fixed, 2, "2.99"},
    {2.99, chars_format::fixed, 1, "3.0"},
    {9.99, chars_format::fixed, 2, "9.99"},
    {9.99, chars_format::fixed, 1, "10.0"},
    {29.99, chars_format::fixed, 2, "29.99"},
    {29.99, chars_format::fixed, 1, "30.0"},
    {99.99, chars_format::fixed, 2, "99.99"},
    {99.99, chars_format::fixed, 1, "100.0"},
    {299.99, chars_format::fixed, 2, "299.99"},
    {299.99, chars_format::fixed, 1, "300.0"},

    {0.9, chars_format::fixed, 1, "0.9"},
    {0.9, chars_format::fixed, 0, "1"},
    {2.9, chars_format::fixed, 1, "2.9"},
    {2.9, chars_format::fixed, 0, "3"},
    {9.9, chars_format::fixed, 1, "9.9"},
    {9.9, chars_format::fixed, 0, "10"},
    {29.9, chars_format::fixed, 1, "29.9"},
    {29.9, chars_format::fixed, 0, "30"},
    {99.9, chars_format::fixed, 1, "99.9"},
    {99.9, chars_format::fixed, 0, "100"},
    {299.9, chars_format::fixed, 1, "299.9"},
    {299.9, chars_format::fixed, 0, "300"},

    // Ryu Printf d2fixed_test.cc D2fixedTest RoundingResultZero
    {0.004, chars_format::fixed, 3, "0.004"},
    {0.004, chars_format::fixed, 2, "0.00"},
    {0.4, chars_format::fixed, 1, "0.4"},
    {0.4, chars_format::fixed, 0, "0"},
    {0.5, chars_format::fixed, 1, "0.5"},
    {0.5, chars_format::fixed, 0, "0"},

    // Ryu Printf d2fixed_test.cc D2fixedTest Regression
    {7.018232e-82, chars_format::fixed, 6, "0.000000"},
};
